package com.ds.lens.data.service.dao;

import com.ds.lens.data.service.dao.entity.LensExternalEvent;
import com.ds.lens.data.service.dao.sql.provider.LensExternalEventSqlProvider;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.JdbcType;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

@Repository
public interface LensExternalEventDao {

    String COLUMNS = " id, monitor_id, version, external_event_type, start_time, end_time, status, reminders, last_reminder_time, created_time ";


    @Delete({
            "delete from lens_external_event",
            "where id = #{id,jdbcType=BIGINT}"
    })
    int deleteByPrimaryKey(Long id);

    @Insert({
            "insert into lens_external_event (id, monitor_id, ",
            "version, external_event_type, ",
            "start_time, end_time, status, ",
            "reminders,last_reminder_time,created_time)",
            "values (#{id,jdbcType=BIGINT}, #{monitorId,jdbcType=BIGINT}, ",
            "#{version,jdbcType=INTEGER}, #{externalEventType,jdbcType=VARCHAR}, ",
            "#{startTime,jdbcType=TIMESTAMP}, #{endTime,jdbcType=TIMESTAMP}, ",
            "#{status,jdbcType=SMALLINT}, #{reminders,jdbcType=INTEGER},  #{lastReminderTime,jdbcType=TIMESTAMP}, #{createdTime,jdbcType=TIMESTAMP})"
    })
    int insert(LensExternalEvent record);

    @InsertProvider(type = LensExternalEventSqlProvider.class, method = "insertSelective")
    int insertSelective(LensExternalEvent record);

    @Select({
            "select",
            COLUMNS,
            "from lens_external_event",
            "where id = #{id,jdbcType=BIGINT}"
    })
    @Results(id = "lensExternalEvent", value = {
            @Result(column = "id", property = "id", jdbcType = JdbcType.BIGINT, id = true),
            @Result(column = "monitor_id", property = "monitorId", jdbcType = JdbcType.BIGINT),
            @Result(column = "version", property = "version", jdbcType = JdbcType.INTEGER),
            @Result(column = "external_event_type", property = "externalEventType", jdbcType = JdbcType.VARCHAR),
            @Result(column = "start_time", property = "startTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "end_time", property = "endTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "status", property = "status", jdbcType = JdbcType.SMALLINT),
            @Result(column = "reminders", property = "reminders", jdbcType = JdbcType.INTEGER),
            @Result(column = "last_reminder_time", property = "lastReminderTime", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "created_time", property = "createdTime", jdbcType = JdbcType.TIMESTAMP)
    })
    LensExternalEvent selectByPrimaryKey(Long id);

    @UpdateProvider(type = LensExternalEventSqlProvider.class, method = "updateByPrimaryKeySelective")
    int updateByPrimaryKeySelective(LensExternalEvent record);

    @Update({
            "update lens_external_event",
            "set monitor_id = #{monitorId,jdbcType=BIGINT},",
            "version = #{version,jdbcType=INTEGER},",
            "external_event_type = #{externalEventType,jdbcType=VARCHAR},",
            "start_time = #{startTime,jdbcType=TIMESTAMP},",
            "end_time = #{endTime,jdbcType=TIMESTAMP},",
            "status = #{status,jdbcType=SMALLINT},",
            "reminders = #{reminders,jdbcType=INTEGER},",
            "last_reminder_time = #{lastReminderTime,jdbcType=TIMESTAMP},",
            "created_time = #{createdTime,jdbcType=TIMESTAMP}",
            "where id = #{id,jdbcType=BIGINT}"
    })
    int updateByPrimaryKey(LensExternalEvent record);

    @Select({
            "select",
            COLUMNS,
            "from lens_external_event",
            "where id = (",
            "select MAX(id) from lens_external_event where monitor_id=#{monitorId,jdbcType=BIGINT}",
            " and external_event_type=#{externalEventType,jdbcType=VARCHAR}",
            " and status = 0",
            ")"
    })
    @ResultMap("lensExternalEvent")
    LensExternalEvent selectLastEvent(@Param("monitorId") Long monitorId,
                                      @Param("externalEventType") String externalEventType);

    @Select({
            "<script>",
            "select",
            COLUMNS,
            "from lens_external_event",
            "where id = (",
            "select MAX(id) from lens_external_event where monitor_id=#{monitorId,jdbcType=BIGINT}",
            "<if test='externalEventType != null'> and external_event_type=#{externalEventType,jdbcType=VARCHAR} </if>",
            " and <![CDATA[start_time < #{time,jdbcType=TIMESTAMP} ]]>",
            "<if test='careStatus'>  and status in (0,1) </if>",
            ")",
            "</script>"
    })
    @ResultMap("lensExternalEvent")
    LensExternalEvent selectExternalEvent(@Param("monitorId") Long monitorId,
                                          @Param("externalEventType") String externalEventType,
                                          @Param("time") Date time,
                                          @Param("careStatus") Boolean careStatus);


    @Select({
            "select",
            COLUMNS,
            "from lens_external_event",
            "where monitor_id=#{monitorId,jdbcType=BIGINT} and status = 0"
    })
    @ResultMap("lensExternalEvent")
    List<LensExternalEvent> selectIncompleteEvents(@Param("monitorId") Long monitorId);

    @Update({
            "update lens_external_event",
            "set reminders = reminders + 1,",
            "last_reminder_time = #{lastReminderTime,jdbcType=TIMESTAMP} ",
            "where id = #{id,jdbcType=BIGINT} and reminders = #{reminders,jdbcType=INTEGER}"
    })
    int updateRemindersById(@Param("id") Long id,
                            @Param("reminders") Integer reminders,
                            @Param("lastReminderTime") Date lastReminderTime);

    @Select({
            "select",
            COLUMNS,
            "from lens_external_event",
            "where status = 0 and reminders < #{reminders,jdbcType=INTEGER}"
    })
    @ResultMap("lensExternalEvent")
    List<LensExternalEvent> selectEventTasks(@Param("reminders") Integer reminders);
}
